package com.ikangtai.shecare.common.al;


import android.content.Context;

import com.ikangtai.shecare.common.App;
import com.ikangtai.shecare.common.db.DBManager;
import com.ikangtai.shecare.common.util.AppLog;
import com.ikangtai.shecare.common.util.DateUtil;
import com.ikangtai.shecare.record.bean.UserRecordData;
import com.ikangtai.shecare.record.bean.UserTemperatureInfo;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;

public class Algorithm {

    private static final int DAY_INPUT_LEN = 10;
    private static final int CYCLE_INPUT_LEN = 3;

    public static int FAKE_DAY_OUT_LEN = 1; //只是为了 execAL 接口的数据类型正确性, 算法实际已不用, dayOutputList才能获取真正的算法结果
    public static int CYCLE_OUT_LEN = 50;

    // alType参数值可能性如下：
    public static final int G2_AL_TYPE_FIRST_TIME = 1; //直接在二代app上注册的用户，第一次算法调用
    public static final int G1_TO_G2_FIRST_LOGIN_AL_TYPE = 102; //一代app用户登录二代app第一次算法调用
    public static final int G2_TO_G2_FIRST_LOGIN_AL_TYPE = 202; //一代app用户登录二代app第一次算法调用

    // 1). 若把“流血”对号改为错号时:
    //     a. 如果此天前后9天都没有标记过“流血”，则调用4.
    //     b. 否则参数为7
    // 2). 输入“流血”，即月经错号变对号，则调用参数为7
    public static final int AL_TYPE_INPUT_MENSES_START = 2;
    public static final int AL_TYPE_INPUT_MENSES_END = 3;
    public static final int AL_TYPE_DELETE_MENSES_START = 4;
    public static final int AL_TYPE_DELETE_MENSES_END = 5;
    public static final int AL_TYPE_ADJUST_HEALTH_INFO_DATE = 6;
    public static final int AL_TYPE_ADJUST_FORECAST_DATE = 7;
    public static final int AL_TYPE_INPUT_MENSES = 7;
    public static final int AL_TYPE_CHANGE_MENSES_PERIOD = 9;
    public static final int AL_TYPE_INPUT_BBT = 11;
    public static final int AL_TYPE_INPUT_MUCUS = 12;
    public static final int AL_TYPE_HISTORY_MENSES_MODIFY = 21;
    public static final int AL_TYPE_HISTORY_MENSES_DELETE = 22;
    public static final int AL_TYPE_HISTORY_BBT_INPUT = 23;

    private DBManager dbManager;
    private DayUnitDSInput[] dayInput = new DayUnitDSInput[DAY_INPUT_LEN]; //第一次为10，且需要初始化空间；之后就是从用户输入获取具体的值(最近一次经期开始到目前的数据)
    private List<DayUnitDSOutput> alDayOutputList; //真正获取算法的dayoutput结果
    private CycleUnitDS[] cycleInput = new CycleUnitDS[CYCLE_INPUT_LEN]; //第一次为3，且需要初始化空间；之后就是从之前的算法获取具体的值
    private DayUnitDSOutput[] fakeDayOutput = new DayUnitDSOutput[FAKE_DAY_OUT_LEN]; //只是为了 execAL 接口的数据类型正确性, 算法实际已不用, dayOutputList才能获取真正的算法结果
    private CycleUnitDS[] cycleOutput = new CycleUnitDS[CYCLE_OUT_LEN];
    private UserUnitDS mUserData;

    public static native int execAL(int type,DayUnitDSInput[] dayInput,int dayInputLength,
                                    CycleUnitDS[] cycleInput, int cycleInputLength,UserUnitDS userdata,long firstPS,
                                    DayUnitDSOutput[] dayOutput, int dayOutputLength, CycleUnitDS[] cycleOutput,int cycleOutputLength);

    static {
        System.loadLibrary("ShecareAlgorithm");
    }

    public Algorithm(Context context){
        dbManager = new DBManager(context);
        mUserData = getALUserDataFromSqlite(App.userName);
    }

    /**
     * 二代app用户登录二代app第一次算法调用，用作弥补后台算法丢失的
     */
    public void g2FirstLoginG2(UserUnitDS userData, DayUnitDSInput[] dayInput, long firstPS){
        AppLog.i("start g1FirstLoginG2!");
        firstInitALInOutputSpace();
        mUserData = userData;
        if(userData == null){
            AppLog.e("FristExecAL argument invalid!");
            return;
        }

        Algorithm.execAL(G2_TO_G2_FIRST_LOGIN_AL_TYPE, dayInput, dayInput.length, cycleInput, cycleInput.length, mUserData, firstPS, fakeDayOutput, FAKE_DAY_OUT_LEN, cycleOutput, CYCLE_OUT_LEN);
        alDayOutputList = ALDayOutputList.getALDayOutputList(G2_TO_G2_FIRST_LOGIN_AL_TYPE, cycleInput, cycleOutput, mUserData);

        polishDayOutput();
    }

    /**
     * 一代app用户登录二代app第一次算法调用
     */
    public void g1FirstLoginG2(UserUnitDS userData, DayUnitDSInput[] dayInput, long firstPS){
        AppLog.i("start g1FirstLoginG2!");
        firstInitALInOutputSpace();
        mUserData = userData;
        if(userData == null){
            AppLog.e("FristExecAL argument invalid!");
            return;
        }
        AppLog.e("dayInput.length:" + dayInput.length);
        
        Algorithm.execAL(G1_TO_G2_FIRST_LOGIN_AL_TYPE, dayInput, dayInput.length, cycleInput, cycleInput.length, mUserData, firstPS, fakeDayOutput, FAKE_DAY_OUT_LEN, cycleOutput, CYCLE_OUT_LEN);
        alDayOutputList = ALDayOutputList.getALDayOutputList(G1_TO_G2_FIRST_LOGIN_AL_TYPE, cycleInput, cycleOutput, mUserData);
        
        polishDayOutput();

    }

    /**
     * 直接在二代app上注册的用户，第一次算法调用, 用户刚注册成功之后调用, userData为用户填写的生理信息，之后的userData从算法返回获取，注意请在子线程里调用此函数!!!
     * 可以在网络请求之后，在onFailure 和 onResponse 子线程里调用!
     * 当onFailure or onResponse code != 200 时, isSynced = 0;
     * 当onResponse code == 200 时, isSynced = 1;
     */
    public void firstExecAL(UserUnitDS userData, long firstPS){
        AppLog.i("start firstExecAL!");
        firstInitALInOutputSpace();
        mUserData = userData;
        if(userData == null || firstPS == 0){
            AppLog.e("FristExecAL argument invalid!");
            return;
        }

        Algorithm.execAL(G2_AL_TYPE_FIRST_TIME, dayInput, dayInput.length, cycleInput, cycleInput.length, mUserData, firstPS, fakeDayOutput, FAKE_DAY_OUT_LEN, cycleOutput, CYCLE_OUT_LEN);
        alDayOutputList = ALDayOutputList.getALDayOutputList(G2_AL_TYPE_FIRST_TIME, cycleInput, cycleOutput, mUserData);
        
        polishDayOutput();
        //saveALData2Sqlite(userData, dayOutput, cycleOutput, isSynced);
    }

    /**
     * 直接在二代app上注册的用户，非第一次算法调用, 注意请在子线程里调用此函数!!!
     * 可以在网络请求之后，在onFailure 和 onResponse 子线程里调用!
     * 当onFailure or onResponse code != 200 时, isSynced = 0;
     * 当onResponse code == 200 时, isSynced = 1;
     *
     * executeAL的调用顺序为先调用月经，然后BBT，然后宫颈粘液
     *
     * 获取executeAL的参数 DayUnitDSInput[] dayInput, CycleUnitDS[] cycleInput
     * 1. dayInput（基于cycleInput得到，因为要根据cycleOutput里的menstruationStartConfirm字段得到本周期开始的第一天）
     *    a). 当前周期BBT(alType = 11) & Mucus dayInput(alType = 12)： 为本周期内的所有历史数据，对应算法分别为 getBBTDayInput() 和 getMucusDayInput()
     *    b). 历史BBT： 编辑的新基础体温数据所在周期的所有的基础体温数据
     *    c). Menses dayInput：
     *          1). 若alType = 2,代表输入经期开始。所有的标记经期的天数，用户新标记的mensRecord设置为255,如果用户经期开始和结束是一起输入的，则直接调用开始255，结束254，一块传输即可;
     *          2). 若alType = 3,代表输入经期结束。所有的标记经期的天数，用户新标记的mensRecord设置为254
     *          3). 若alType = 4,代表删除经期开始。所有的标记经期的天数，用户删除的mensRecord设置为255
     *          4). 若alType = 5,代表删除经期结束。所有的标记经期的天数，用户删除的mensRecord设置为254
     *          5). 若alType = 6,是为了校正预测经期开始到明天，输入同2
     * 2. cycleInput
     *    a). 当前周期BBT & Mucus cycleInput： 为userData里对应的cycleNum然后+1得到的值cycleNum'，
     *        即为对应cycleOutput表里值为cycleNum'的那行数据,对应算法为 getBBTMucusCycleInput()。
     *    b). Menses cycleInput,对应算法为 getMensesCycleInput()：
     *           1). 若alType = 2,3，4, 5， 所有的有确定经期开始的cycle，无确定的不传
     *           2). 若alType = 7, 为cycleOutput表里的所有数据
     */
    public int executeAL(int alType, DayUnitDSInput[] dayInput, CycleUnitDS[] cycleInput, int isSynced){

        if(!isALTypeValid(alType) || mUserData == null ||
                dayInput == null || cycleInput == null){
            AppLog.e("executeAL argument invalid!");
            return 0;
        }

        initALOutputSpace();
        AppLog.i("start Algorithm");
        int result = Algorithm.execAL(alType, dayInput, dayInput.length, cycleInput, cycleInput.length, mUserData, 0, fakeDayOutput, FAKE_DAY_OUT_LEN, cycleOutput, CYCLE_OUT_LEN);
        alDayOutputList = ALDayOutputList.getALDayOutputList(alType, cycleInput, cycleOutput, mUserData);
        
        AppLog.i("end Algorithm and result = " + result);
        if(234 == result) return result;
        else{
            polishDayOutput();
        if(!(236 == result)){
            if(alType == 4){
                filterDayOutputWithInvalidTime();
                filterCycleOutput();
            }
        }
            saveALData2Sqlite(mUserData, alDayOutputList, cycleOutput, isSynced);
            return result;
        }
    }

    private void filterDayOutputWithInvalidTime() {

        if(alDayOutputList.size() != 0){
            List<DayUnitDSOutput> dayUnitDSOutputList = new ArrayList<DayUnitDSOutput>();
            dayUnitDSOutputList.clear();
            for(int i = 0; i < alDayOutputList.size(); i++){
                if (!DateUtil.isValidDate(alDayOutputList.get(i).date)) continue;
                dayUnitDSOutputList.add(alDayOutputList.get(i));
            }
            if(dayUnitDSOutputList.size() != 0 && dayUnitDSOutputList.get(0).periodAchieveForecast == 99){
                long dateNewStart = dayUnitDSOutputList.get(0).date;
                List<DayUnitDSOutput> dayUnitDSOutputList1 = dbManager.getALDayUnitDSOutputList(App.userName, 0, dateNewStart);
                for(int i = 0; i < dayUnitDSOutputList1.size(); i++){
                    dayUnitDSOutputList1.get(i).periodAchieveForecast = 99;
                }
                dbManager.saveALDayOutput(dayUnitDSOutputList1, 0);
            }
        }
    }


    private void filterCycleOutput() {

        CycleUnitDS[] cycleUnitDSes = dbManager.getALCycleOutput(App.userName, null);
        if(null != cycleUnitDSes && cycleUnitDSes.length > 0){
            for(int i = 0; i < cycleUnitDSes.length; i++){
                cycleUnitDSes[i].ovulationDayUserRecordBasis = -99;
                AppLog.e("filterCycleOutput cycleMenstruationStartConfirm:" + DateUtil.getDateTimeStr2bit(cycleUnitDSes[i].menstruationStartConfirm));
            }
            dbManager.saveALCycleOutput(cycleUnitDSes, 0);
        }

    }

    private void polishDayOutput() {
        if(alDayOutputList.size() != 0){
            for(int i = 0; i < alDayOutputList.size(); i++){
                alDayOutputList.get(i).showLog();
                long date = alDayOutputList.get(i).date;
                long datePolish = DateUtil.getStringToDate(DateUtil.getDateStr2bit(date) + " 12:00:00");
                alDayOutputList.get(i).date = datePolish;
            }
        }
    }

    /**
     * 修改生理信息调用算法
     * @param dayInput 本周期内月经流血的流血开始日和流血结束日的dayInput
     * @param cycleInput 所有的
     * @param userdata 修改后的userdata
     * @param isSynced sync 0/1
     */
    public int chgHealthInfoAL(DayUnitDSInput[] dayInput, CycleUnitDS[] cycleInput, UserUnitDS userdata, int isSynced){
        initALOutputSpace();
        AppLog.i("start Algorithm");
        mUserData = userdata;
        int result = Algorithm.execAL(AL_TYPE_ADJUST_HEALTH_INFO_DATE, dayInput, dayInput.length, cycleInput, cycleInput.length, mUserData, 0, fakeDayOutput, FAKE_DAY_OUT_LEN, cycleOutput, CYCLE_OUT_LEN);
        alDayOutputList = ALDayOutputList.getALDayOutputList(AL_TYPE_ADJUST_HEALTH_INFO_DATE, cycleInput, cycleOutput, mUserData);
        
        AppLog.i("end Algorithm");
        polishDayOutput();
        saveALData2Sqlite(mUserData, alDayOutputList, cycleOutput, isSynced);
        return result;
    }

    public CycleUnitDS[] getBBTMucusCycleInput(){
//        int cycleNum = mUserData.validCycleCount + 1;
//        AppLog.e("getBBTMucusCycleInput cycleNum:" + cycleNum);

        CycleUnitDS[] currentBBTMucusCycleInput = dbManager.getCurrentDayCycle(App.userName);

        return currentBBTMucusCycleInput;

    }

    public CycleUnitDS[] getHistoryBBTCycleInput(long recordDate){
        int cycleNum = dbManager.getSelectedDayCycleUnitDSNum(App.userName, recordDate);
        CycleUnitDS cycleUnitDS = getALCycleOutputFromSqlite(App.userName, String.valueOf(cycleNum))[0];
        long cycleMensesStart = cycleUnitDS.menstruationStartConfirm > 0 ? cycleUnitDS.menstruationStartConfirm : cycleUnitDS.menstruationStartForecast;
        CycleUnitDS cycleUnitDSNext = getALCycleOutputFromSqlite(App.userName, String.valueOf(cycleNum + 1))[0];
        long cycleMensesStartNext = cycleUnitDSNext.menstruationStartConfirm > 0 ? cycleUnitDSNext.menstruationStartConfirm : cycleUnitDSNext.menstruationStartForecast;
        CycleUnitDS[] cycleUnitDSs = new CycleUnitDS[2];
        cycleUnitDSs[0] = cycleUnitDS;
        cycleUnitDSs[1] = cycleUnitDSNext;
        return cycleUnitDSs;
    }

    public CycleUnitDS[] getMensesCycleInput(int alType){

        CycleUnitDS[] cycleUnitDS = null;

        switch (alType){
            case AL_TYPE_DELETE_MENSES_START:
                cycleUnitDS = new CycleUnitDS[2];
                cycleUnitDS[0] =  getALCycleOutputFromSqlite(App.userName, String.valueOf(mUserData.validCycleCount))[0];
                cycleUnitDS[1] =  getALCycleOutputFromSqlite(App.userName, String.valueOf(mUserData.validCycleCount + 1))[0];
                break;

            case AL_TYPE_INPUT_MENSES:
                cycleUnitDS =  getALCycleOutputFromSqlite(App.userName, null);

                break;
        }

        return cycleUnitDS;
    }

    //获取确定的经期开始大于2012.1.1的cycle
    public CycleUnitDS[] getMensesHistoryCycleInput(){

        CycleUnitDS[] cycleUnitDS = dbManager.getHistoryChangeALCycleOutput(App.userName);

        return cycleUnitDS;
    }

    //获取全部有确定经期开始的cycle
    public CycleUnitDS[] getAllMensesConfirmStartHaveALCycleOutput(){

        CycleUnitDS[] cycleUnitDS = dbManager.getAllMensesConfirmStartHaveALCycleOutput(App.userName);

        return cycleUnitDS;
    }

    public DayUnitDSInput[] getBBTDayInput(){
        long mensesStartTime = getMensesStartTime();
        AppLog.e("getBBTDayInput mensesStartTime:" + mensesStartTime);
        List<UserTemperatureInfo> userTemperatureInfos = dbManager.getTemperatureList(App.userName, mensesStartTime);

        DayUnitDSInput[] dayUnitDSInput = new DayUnitDSInput[userTemperatureInfos.size()];
        AppLog.i("userTemperatureInfos.size():" + userTemperatureInfos.size());
        for(int i = 0; i < dayUnitDSInput.length; i++){
            AppLog.i("" + userTemperatureInfos.get(i).getMeasureTime());
            dayUnitDSInput[i] = new DayUnitDSInput();
            dayUnitDSInput[i].date = DateUtil.getDateZeroTime2bit(userTemperatureInfos.get(i).getMeasureTime());
            double originalBBT = userTemperatureInfos.get(i).getTemperature();
            dayUnitDSInput[i].BBT = getPolishedBBT(originalBBT);
            dayUnitDSInput[i].dayOfCycle = 0;
            dayUnitDSInput[i].menstruationRecord = 0;
            dayUnitDSInput[i].cervicalMunusRecord = 0;
            dayUnitDSInput[i].ovulationTestResult = 0;
            dayUnitDSInput[i].tempFlag = 0;
            dayUnitDSInput[i].showLog();
        }

        return dayUnitDSInput;
    }

    public DayUnitDSInput[] getHistoryBBTDayInput(long recordDate){
        int cycleNum = dbManager.getSelectedDayCycleUnitDSNum(App.userName, recordDate);
        AppLog.e("cycleNum:" + cycleNum);
        CycleUnitDS cycleUnitDS = getALCycleOutputFromSqlite(App.userName, String.valueOf(cycleNum))[0];
        long cycleMensesStart = cycleUnitDS.menstruationStartConfirm > 0 ? cycleUnitDS.menstruationStartConfirm : cycleUnitDS.menstruationStartForecast;
        CycleUnitDS cycleUnitDSNext = getALCycleOutputFromSqlite(App.userName, String.valueOf(cycleNum + 1))[0];
        long cycleMensesStartNext = cycleUnitDSNext.menstruationStartConfirm > 0 ? cycleUnitDSNext.menstruationStartConfirm : cycleUnitDSNext.menstruationStartForecast;
        List<UserTemperatureInfo> userTemperatureInfos = dbManager.getTemperatureList(App.userName, cycleMensesStart - 12 * 3600, cycleMensesStartNext - 12 * 3600);

        DayUnitDSInput[] dayUnitDSInput = new DayUnitDSInput[userTemperatureInfos.size()];
        AppLog.i("userTemperatureInfos.size():" + userTemperatureInfos.size());
        for(int i = 0; i < dayUnitDSInput.length; i++){
            AppLog.i("" + userTemperatureInfos.get(i).getMeasureTime());
            dayUnitDSInput[i] = new DayUnitDSInput();
            dayUnitDSInput[i].date = DateUtil.getDateZeroTime2bit(userTemperatureInfos.get(i).getMeasureTime());
            double originalBBT = userTemperatureInfos.get(i).getTemperature();
            dayUnitDSInput[i].BBT = getPolishedBBT(originalBBT);
            dayUnitDSInput[i].dayOfCycle = 0;
            dayUnitDSInput[i].menstruationRecord = 0;
            dayUnitDSInput[i].cervicalMunusRecord = 0;
            dayUnitDSInput[i].ovulationTestResult = 0;
            dayUnitDSInput[i].tempFlag = 0;
            dayUnitDSInput[i].showLog();
        }
        return dayUnitDSInput;
    }

    public DayUnitDSInput[] getMucusDayInput(){
        long mensesStartTime = getMensesStartTime();
        List<UserRecordData> userRecordDataList = dbManager.getRecordDataList(App.userName, mensesStartTime);

        DayUnitDSInput[] dayUnitDSInput = new DayUnitDSInput[userRecordDataList.size()];

        for(int i = 0; i < dayUnitDSInput.length; i++){
            dayUnitDSInput[i] = new DayUnitDSInput();
            dayUnitDSInput[i].date = DateUtil.getDateZeroTime2bit(userRecordDataList.get(i).getRecordDate());
            dayUnitDSInput[i].BBT = 0;
            dayUnitDSInput[i].dayOfCycle = 0;
            dayUnitDSInput[i].menstruationRecord = 0;
            dayUnitDSInput[i].cervicalMunusRecord = userRecordDataList.get(i).getMucusStatusValue();
            dayUnitDSInput[i].ovulationTestResult = 0;
            dayUnitDSInput[i].tempFlag = 0;
        }

        return dayUnitDSInput;
    }

    public DayUnitDSInput[] getMensesDayInput1(long recordDateSeconds, int alType){

        DayUnitDSInput[] dayUnitDSInput = null;

        switch (alType){
            case AL_TYPE_DELETE_MENSES_START:
                dayUnitDSInput = getDeleteMensesDayInput(recordDateSeconds);
                break;

            case AL_TYPE_INPUT_MENSES:
                dayUnitDSInput = getInputMensesDayInput(recordDateSeconds);
                break;
        }

        return dayUnitDSInput;
    }

    public DayUnitDSInput[] getMensesDayInput(long recordDateSeconds, int alType){

        DayUnitDSInput[] dayUnitDSInput = null;

        switch (alType){
            case AL_TYPE_DELETE_MENSES_START:
                dayUnitDSInput = getDeleteMensesStartDayInput(recordDateSeconds);
                break;

            case AL_TYPE_DELETE_MENSES_END:
                dayUnitDSInput = getDeleteMensesEndDayInput(recordDateSeconds);
                break;

            case AL_TYPE_INPUT_MENSES_START:
                dayUnitDSInput = getInputMensesStartDayInput(recordDateSeconds);
                break;

            case AL_TYPE_INPUT_MENSES_END:
                dayUnitDSInput = getInputMensesEndDayInput(recordDateSeconds);
                break;
        }
        return dayUnitDSInput;
    }

    public DayUnitDSInput[] getHistoryModifyMensesDayInput(long recordDateSeconds, int alType, boolean  isStart){

        DayUnitDSInput[] dayUnitDSInput = null;

        switch (alType){
            case AL_TYPE_HISTORY_MENSES_DELETE:
                dayUnitDSInput = getDeleteHistoryMensesDayInput(recordDateSeconds);
                break;

            case AL_TYPE_HISTORY_MENSES_MODIFY:
                dayUnitDSInput = getModifyHistoryMensesDayInput(recordDateSeconds, isStart);
                break;
        }

        return dayUnitDSInput;
    }

    //单位：秒数时间戳
    private long getMensesStartTime(){
        CycleUnitDS[] cycleUnitDS = getBBTMucusCycleInput();
        // cycleOutput里menstruationStartConfirm存的是当天12：00的秒数，减去12个小时的秒数作为基数，
        // 在BBT & Mucus表里大于此基数的秒数的行数据均为此周期内的数据
        return cycleUnitDS[0].menstruationStartConfirm - 12 * 3600;
    }

    private float getPolishedBBT(double originalBBT){
        double usefulFloat = originalBBT * 10.0f;
        double intPart = Math.floor(usefulFloat);
        double floatPart = usefulFloat - intPart;
        if (floatPart < 0.3f) {
            floatPart = 0.0f;
        } else if (floatPart < 0.8f) {
            floatPart = 0.5f;
        } else {
            floatPart = 1.0f;
        }

        double result = Math.round((intPart + floatPart) * 10) * 0.01;
        return Float.valueOf(String.valueOf(result));
    }

    // alType = 2
    private DayUnitDSInput[] getInputMensesStartDayInput(long recordDateSeconds){
        deleteInputMensesDayNoValidRecordDatas(recordDateSeconds, AL_TYPE_INPUT_MENSES_START);
        long startTime = DateUtil.getStringToDate("2012-01-01 00:00:00");
        AppLog.i("startTime:" + startTime);
        List<UserRecordData> userRecordDataList = dbManager.getRecordDataList(App.userName, startTime);
        int bloodRecordNum = getBloodRecordNum(userRecordDataList);
        AppLog.i("bloodRecordNum size:" + bloodRecordNum);
        DayUnitDSInput[] dayUnitDSInput = new DayUnitDSInput[bloodRecordNum];

        for(int  i = userRecordDataList.size() - 1; i >=  0; i--){
            if(!UserRecordData.isMensesBlood(userRecordDataList.get(i).getMensesInfo())) {
                userRecordDataList.remove(i);
            }
        }

        for(int i = 0; i < dayUnitDSInput.length; i++){
            //if(UserRecordData.isMensesBlood(userRecordDataList.get(i).getMensesInfo())) {
            dayUnitDSInput[i] = new DayUnitDSInput();
            dayUnitDSInput[i].date = DateUtil.getDateZeroTime2bit(userRecordDataList.get(i).getRecordDate());
            dayUnitDSInput[i].BBT = 0;
            dayUnitDSInput[i].dayOfCycle = 0;
            if(DateUtil.getDateZeroTime2bit(userRecordDataList.get(i).getRecordDate()) == DateUtil.getDateZeroTime2bit(recordDateSeconds))
                dayUnitDSInput[i].menstruationRecord = 255;
            else
                dayUnitDSInput[i].menstruationRecord = 1;
            dayUnitDSInput[i].cervicalMunusRecord = 0;
            dayUnitDSInput[i].ovulationTestResult = 0;
            dayUnitDSInput[i].tempFlag = 0;
            dayUnitDSInput[i].showLog();
            AppLog.i("dayUnitDSInput date:" + dayUnitDSInput[i].date + "  dayUnitDSInput menstruationRecord:" + dayUnitDSInput[i].menstruationRecord);
            // }
        }
        return dayUnitDSInput;
    }

    // alType = 3
    private DayUnitDSInput[] getInputMensesEndDayInput(long recordDateSeconds){
        deleteInputMensesDayNoValidRecordDatas(recordDateSeconds, AL_TYPE_INPUT_MENSES_END);
        long startTime = DateUtil.getStringToDate("2012-01-01 00:00:00");
        AppLog.i("startTime:" + startTime);
        List<UserRecordData> userRecordDataList = dbManager.getRecordDataList(App.userName, startTime);
        int bloodRecordNum = getBloodRecordNum(userRecordDataList);
        AppLog.i("bloodRecordNum size:" + bloodRecordNum);
        DayUnitDSInput[] dayUnitDSInput = new DayUnitDSInput[bloodRecordNum];

        for(int  i = userRecordDataList.size() - 1; i >=  0; i--){
            if(!UserRecordData.isMensesBlood(userRecordDataList.get(i).getMensesInfo())) {
                userRecordDataList.remove(i);
            }
        }

        for(int i = 0; i < dayUnitDSInput.length; i++){
            //if(UserRecordData.isMensesBlood(userRecordDataList.get(i).getMensesInfo())) {
            dayUnitDSInput[i] = new DayUnitDSInput();
            dayUnitDSInput[i].date = DateUtil.getDateZeroTime2bit(userRecordDataList.get(i).getRecordDate());
            dayUnitDSInput[i].BBT = 0;
            dayUnitDSInput[i].dayOfCycle = 0;
            if(DateUtil.getDateZeroTime2bit(userRecordDataList.get(i).getRecordDate()) == DateUtil.getDateZeroTime2bit(recordDateSeconds))
                dayUnitDSInput[i].menstruationRecord = 254;
            else
                dayUnitDSInput[i].menstruationRecord = 1;
            dayUnitDSInput[i].cervicalMunusRecord = 0;
            dayUnitDSInput[i].ovulationTestResult = 0;
            dayUnitDSInput[i].tempFlag = 0;
            dayUnitDSInput[i].showLog();
            AppLog.i("dayUnitDSInput date:" + dayUnitDSInput[i].date + "  dayUnitDSInput menstruationRecord:" + dayUnitDSInput[i].menstruationRecord);
            // }
        }
        return dayUnitDSInput;
    }

    // alType = 4
    private DayUnitDSInput[] getDeleteMensesStartDayInput(long recordDateSeconds){
        //long startTime = DateUtil.getForthOrBackDateZeroTime(recordDateSeconds, 0);
        deleteInputMensesDayNoValidRecordDatas(recordDateSeconds, AL_TYPE_DELETE_MENSES_START);
        long startTime = DateUtil.getStringToDate("2012-01-01 00:00:00");
        AppLog.i("startTime:" + startTime);
        List<UserRecordData> userRecordDataList = dbManager.getRecordDataList(App.userName, startTime);
        int bloodRecordNum = getBloodRecordNum(userRecordDataList);
        AppLog.i("bloodRecordNum size:" + bloodRecordNum);
        DayUnitDSInput[] dayUnitDSInput = new DayUnitDSInput[bloodRecordNum + 1];

        for(int  i = userRecordDataList.size() - 1; i >=  0; i--){
            if(!UserRecordData.isMensesBlood(userRecordDataList.get(i).getMensesInfo())) {
                userRecordDataList.remove(i);
            }
        }
        int removePosition = 0;
        for(int  i = userRecordDataList.size() - 1; i >=  0; i--){
            if(userRecordDataList.get(i).getRecordDate() < DateUtil.getDateZeroTime2bit(recordDateSeconds) ) {
                removePosition = i + 1;
                break;
            }else{
                removePosition = 0;
            }
        }
        List<UserRecordData> userRecordDataListAddRemovePosition = new ArrayList<UserRecordData>();
        userRecordDataListAddRemovePosition.clear();
        if(removePosition == 0){
            UserRecordData userRecordDataRemoved = new UserRecordData();
            userRecordDataRemoved.setRecordDate(DateUtil.getDateZeroTime2bit(recordDateSeconds));
            userRecordDataRemoved.setMensesInfo(255);
            userRecordDataListAddRemovePosition.add(userRecordDataRemoved);
            for(int i = 0; i < userRecordDataList.size(); i++ ){
                userRecordDataListAddRemovePosition.add(userRecordDataList.get(i));
            }
        }else{
            for(int i = 0; i < removePosition; i++){
                userRecordDataListAddRemovePosition.add(userRecordDataList.get(i));
            }
            UserRecordData userRecordDataRemoved = new UserRecordData();
            userRecordDataRemoved.setRecordDate(DateUtil.getDateZeroTime2bit(recordDateSeconds));
            userRecordDataRemoved.setMensesInfo(255);
            userRecordDataListAddRemovePosition.add(userRecordDataRemoved);
            for(int i = removePosition; i < userRecordDataList.size(); i++){
                userRecordDataListAddRemovePosition.add(userRecordDataList.get(i));
            }
        }

        for(int i = 0; i < dayUnitDSInput.length; i++){
            //if(UserRecordData.isMensesBlood(userRecordDataList.get(i).getMensesInfo())) {
            dayUnitDSInput[i] = new DayUnitDSInput();
            dayUnitDSInput[i].date = DateUtil.getDateZeroTime2bit(userRecordDataListAddRemovePosition.get(i).getRecordDate());
            dayUnitDSInput[i].BBT = 0;
            dayUnitDSInput[i].dayOfCycle = 0;
            dayUnitDSInput[i].menstruationRecord = userRecordDataListAddRemovePosition.get(i).getMensesInfo();
            dayUnitDSInput[i].cervicalMunusRecord = 0;
            dayUnitDSInput[i].ovulationTestResult = 0;
            dayUnitDSInput[i].tempFlag = 0;
            dayUnitDSInput[i].showLog();
            AppLog.i("dayUnitDSInput date:" + dayUnitDSInput[i].date + "  dayUnitDSInput menstruationRecord:" + dayUnitDSInput[i].menstruationRecord);
            // }
        }
        return dayUnitDSInput;
    }

    // alType = 5
    private DayUnitDSInput[] getDeleteMensesEndDayInput(long recordDateSeconds){
        //long startTime = DateUtil.getForthOrBackDateZeroTime(recordDateSeconds, 0);
        deleteInputMensesDayNoValidRecordDatas(recordDateSeconds, AL_TYPE_DELETE_MENSES_END);
        long startTime = DateUtil.getStringToDate("2012-01-01 00:00:00");
        AppLog.i("startTime:" + startTime);
        List<UserRecordData> userRecordDataList = dbManager.getRecordDataList(App.userName, startTime);
        int bloodRecordNum = getBloodRecordNum(userRecordDataList);
        AppLog.i("bloodRecordNum size:" + bloodRecordNum);
        DayUnitDSInput[] dayUnitDSInput = new DayUnitDSInput[bloodRecordNum + 1];

        for(int  i = userRecordDataList.size() - 1; i >=  0; i--){
            if(!UserRecordData.isMensesBlood(userRecordDataList.get(i).getMensesInfo())) {
                userRecordDataList.remove(i);
            }
        }
        int removePosition = 0;
        for(int  i = userRecordDataList.size() - 1; i >=  0; i--){
            if(userRecordDataList.get(i).getRecordDate() < DateUtil.getDateZeroTime2bit(recordDateSeconds) ) {
                removePosition = i + 1;
                break;
            }else{
                removePosition = 0;
            }
        }
        List<UserRecordData> userRecordDataListAddRemovePosition = new ArrayList<UserRecordData>();
        userRecordDataListAddRemovePosition.clear();
        if(removePosition == 0){
            UserRecordData userRecordDataRemoved = new UserRecordData();
            userRecordDataRemoved.setRecordDate(DateUtil.getDateZeroTime2bit(recordDateSeconds));
            userRecordDataRemoved.setMensesInfo(254);
            userRecordDataListAddRemovePosition.add(userRecordDataRemoved);
            for(int i = 0; i < userRecordDataList.size(); i++ ){
                userRecordDataListAddRemovePosition.add(userRecordDataList.get(i));
            }
        }else{
            for(int i = 0; i < removePosition; i++){
                userRecordDataListAddRemovePosition.add(userRecordDataList.get(i));
            }
            UserRecordData userRecordDataRemoved = new UserRecordData();
            userRecordDataRemoved.setRecordDate(DateUtil.getDateZeroTime2bit(recordDateSeconds));
            userRecordDataRemoved.setMensesInfo(254);
            userRecordDataListAddRemovePosition.add(userRecordDataRemoved);
            for(int i = removePosition; i < userRecordDataList.size(); i++){
                userRecordDataListAddRemovePosition.add(userRecordDataList.get(i));
            }
        }
        for(int i = 0; i < dayUnitDSInput.length; i++){
            //if(UserRecordData.isMensesBlood(userRecordDataList.get(i).getMensesInfo())) {
            dayUnitDSInput[i] = new DayUnitDSInput();
            dayUnitDSInput[i].date = DateUtil.getDateZeroTime2bit(userRecordDataListAddRemovePosition.get(i).getRecordDate());
            dayUnitDSInput[i].BBT = 0;
            dayUnitDSInput[i].dayOfCycle = 0;
            dayUnitDSInput[i].menstruationRecord = userRecordDataListAddRemovePosition.get(i).getMensesInfo();
            dayUnitDSInput[i].cervicalMunusRecord = 0;
            dayUnitDSInput[i].ovulationTestResult = 0;
            dayUnitDSInput[i].tempFlag = 0;
            dayUnitDSInput[i].showLog();
            AppLog.i("dayUnitDSInput date:" + dayUnitDSInput[i].date + "  dayUnitDSInput menstruationRecord:" + dayUnitDSInput[i].menstruationRecord);
            // }
        }
        return dayUnitDSInput;
    }

    // alType = 4
    private DayUnitDSInput[] getDeleteMensesDayInput(long recordDateSeconds){
        long startTime = DateUtil.getForthOrBackDateZeroTime(recordDateSeconds, 0);
        long endTime = DateUtil.getForthOrBackDateZeroTime(recordDateSeconds, 1);
        List<DayUnitDSOutput> dayUnitDSOutputList = dbManager.getALDayUnitDSOutputList(App.userName, startTime, endTime);

        DayUnitDSInput[] dayUnitDSInput = new DayUnitDSInput[dayUnitDSOutputList.size()];

        for(int i = 0; i < dayUnitDSInput.length; i++){
            dayUnitDSInput[i] = new DayUnitDSInput();
            dayUnitDSInput[i].date = dayUnitDSOutputList.get(i).date;
            dayUnitDSInput[i].BBT = 0;
            dayUnitDSInput[i].dayOfCycle = dayUnitDSOutputList.get(i).dayOfCycle;
            dayUnitDSInput[i].menstruationRecord = 1;
            dayUnitDSInput[i].cervicalMunusRecord = 0;
            dayUnitDSInput[i].ovulationTestResult = 0;
            dayUnitDSInput[i].tempFlag = 0;
            AppLog.i("dayUnitDSInput date:" + dayUnitDSInput[i].date + "  dayUnitDSInput menstruationRecord:" + dayUnitDSInput[i].menstruationRecord);
        }

        return dayUnitDSInput;
    }

    // alType = 6
    public DayUnitDSInput[] getModifyHealthInfoMensesInput(long recordDateSeconds){
        long startTime = DateUtil.getStringToDate("2012-01-01 00:00:00");
        AppLog.i("startTime:" + startTime);
        List<UserRecordData> userRecordDataList = dbManager.getRecordDataList(App.userName, startTime);
        int bloodRecordNum = getBloodRecordNum(userRecordDataList);
        AppLog.i("bloodRecordNum size:" + bloodRecordNum);
        DayUnitDSInput[] dayUnitDSInput = new DayUnitDSInput[bloodRecordNum];

        for(int  i = userRecordDataList.size() - 1; i >=  0; i--){
            if(!UserRecordData.isMensesBlood(userRecordDataList.get(i).getMensesInfo())) {
                userRecordDataList.remove(i);
            }
        }

        for(int i = 0; i < dayUnitDSInput.length; i++){
            //if(UserRecordData.isMensesBlood(userRecordDataList.get(i).getMensesInfo())) {
            dayUnitDSInput[i] = new DayUnitDSInput();
            dayUnitDSInput[i].date = DateUtil.getDateZeroTime2bit(userRecordDataList.get(i).getRecordDate());
            dayUnitDSInput[i].BBT = 0;
            dayUnitDSInput[i].dayOfCycle = 0;
            if(DateUtil.getDateZeroTime2bit(userRecordDataList.get(i).getRecordDate()) == DateUtil.getDateZeroTime2bit(recordDateSeconds))
                dayUnitDSInput[i].menstruationRecord = 255;
            else
                dayUnitDSInput[i].menstruationRecord = 1;
            dayUnitDSInput[i].cervicalMunusRecord = 0;
            dayUnitDSInput[i].ovulationTestResult = 0;
            dayUnitDSInput[i].tempFlag = 0;
            dayUnitDSInput[i].showLog();
            AppLog.i("dayUnitDSInput date:" + dayUnitDSInput[i].date + "  dayUnitDSInput menstruationRecord:" + dayUnitDSInput[i].menstruationRecord);
            // }
        }
        return dayUnitDSInput;
    }

    // alType = 7
    public DayUnitDSInput[] getChangeForecastMensesStartDayInput(long recordDateSeconds){
        long startTime = DateUtil.getStringToDate("2012-01-01 00:00:00");
        AppLog.i("startTime:" + startTime);
        List<UserRecordData> userRecordDataList = dbManager.getRecordDataList(App.userName, startTime);
        int bloodRecordNum = getBloodRecordNum(userRecordDataList);
        AppLog.i("bloodRecordNum size:" + bloodRecordNum);
        DayUnitDSInput[] dayUnitDSInput = new DayUnitDSInput[bloodRecordNum + 1];

        for(int  i = userRecordDataList.size() - 1; i >=  0; i--){
            if(!UserRecordData.isMensesBlood(userRecordDataList.get(i).getMensesInfo())) {
                userRecordDataList.remove(i);
            }
        }

        for(int i = 0; i < dayUnitDSInput.length - 1; i++){
            //if(UserRecordData.isMensesBlood(userRecordDataList.get(i).getMensesInfo())) {
            dayUnitDSInput[i] = new DayUnitDSInput();
            dayUnitDSInput[i].date = DateUtil.getDateZeroTime2bit(userRecordDataList.get(i).getRecordDate());
            dayUnitDSInput[i].BBT = 0;
            dayUnitDSInput[i].dayOfCycle = 0;
            dayUnitDSInput[i].menstruationRecord = 1;
            dayUnitDSInput[i].cervicalMunusRecord = 0;
            dayUnitDSInput[i].ovulationTestResult = 0;
            dayUnitDSInput[i].tempFlag = 0;
            dayUnitDSInput[i].showLog();
            AppLog.i("dayUnitDSInput date:" + dayUnitDSInput[i].date + "  dayUnitDSInput menstruationRecord:" + dayUnitDSInput[i].menstruationRecord);
            // }
        }
        dayUnitDSInput[dayUnitDSInput.length - 1] = new DayUnitDSInput();
        dayUnitDSInput[dayUnitDSInput.length - 1].date = recordDateSeconds + 12 * 3600 + 24 * 3600;
        dayUnitDSInput[dayUnitDSInput.length - 1].menstruationRecord = 255;
        return dayUnitDSInput;
    }
    // alType = 22  参数为历史姨妈来了日期零时时间戳
    private DayUnitDSInput[] getDeleteHistoryMensesDayInput(long recordDateSeconds){
        long startTime = recordDateSeconds;
        long endTime = DateUtil.getForthOrBackDateZeroTime(recordDateSeconds, 1);
        List<DayUnitDSOutput> dayUnitDSOutputList = dbManager.getALDayUnitDSOutputList(App.userName, startTime, endTime);

        DayUnitDSInput[] dayUnitDSInput = new DayUnitDSInput[dayUnitDSOutputList.size()];

        for(int i = 0; i < dayUnitDSInput.length; i++){
            dayUnitDSInput[i] = new DayUnitDSInput();
            dayUnitDSInput[i].date = dayUnitDSOutputList.get(i).date;
            dayUnitDSInput[i].BBT = 0;
            dayUnitDSInput[i].dayOfCycle = dayUnitDSOutputList.get(i).dayOfCycle;
            dayUnitDSInput[i].menstruationRecord = 255;
            dayUnitDSInput[i].cervicalMunusRecord = 0;
            dayUnitDSInput[i].ovulationTestResult = 0;
            dayUnitDSInput[i].tempFlag = 0;
            AppLog.i("dayUnitDSInput date:" + dayUnitDSInput[i].date + "  dayUnitDSInput menstruationRecord:" + dayUnitDSInput[i].menstruationRecord);
        }

        return dayUnitDSInput;
    }

    // alType = 7
    private DayUnitDSInput[] getInputMensesDayInput(long recordDateSeconds){
        //long startTime = DateUtil.getForthOrBackDateZeroTime(recordDateSeconds, 0);
        long startTime = getInputMensesStartTime(recordDateSeconds);
        AppLog.i("startTime:" + startTime);
        long endTime = DateUtil.getForthOrBackDateZeroTime(startTime, 15);
        AppLog.i("endTime:" + endTime);
        List<UserRecordData> userRecordDataList = dbManager.getRecordDataList(App.userName, startTime, endTime);
        int bloodRecordNum = getBloodRecordNum(userRecordDataList);
        AppLog.i("bloodRecordNum size:" + bloodRecordNum);
        DayUnitDSInput[] dayUnitDSInput = new DayUnitDSInput[bloodRecordNum];

        for(int  i = userRecordDataList.size() - 1; i >=  0; i--){
            if(!UserRecordData.isMensesBlood(userRecordDataList.get(i).getMensesInfo())) {
                userRecordDataList.remove(i);
            }
        }

        for(int i = 0; i < dayUnitDSInput.length; i++){
            //if(UserRecordData.isMensesBlood(userRecordDataList.get(i).getMensesInfo())) {
                dayUnitDSInput[i] = new DayUnitDSInput();
                dayUnitDSInput[i].date = DateUtil.getDateZeroTime2bit(userRecordDataList.get(i).getRecordDate());
                dayUnitDSInput[i].BBT = 0;
                dayUnitDSInput[i].dayOfCycle = 0;
                dayUnitDSInput[i].menstruationRecord = 1;
                dayUnitDSInput[i].cervicalMunusRecord = 0;
                dayUnitDSInput[i].ovulationTestResult = 0;
                dayUnitDSInput[i].tempFlag = 0;
                dayUnitDSInput[i].showLog();
            AppLog.i("dayUnitDSInput date:" + dayUnitDSInput[i].date + "  dayUnitDSInput menstruationRecord:" + dayUnitDSInput[i].menstruationRecord);
           // }
        }

        return dayUnitDSInput;
    }

    // alType = 21  参数为历史姨妈来了日期零时时间戳  是否月经开始
    private DayUnitDSInput[] getModifyHistoryMensesDayInput(long recordDateSeconds, boolean isStart){

        if(isStart){
            boolean hasEnd = false;
            int position = 0;
            long startTime = recordDateSeconds;
            long endTime = recordDateSeconds + (15 + App.memory_preference_mensesLen) * 24 * 3600;
            List<DayUnitDSOutput> dayUnitDSOutputList = dbManager.getALDayUnitDSOutputList(App.userName, startTime, endTime);
            for(int i = 0; i < dayUnitDSOutputList.size(); i++){
                if(dayUnitDSOutputList.get(i).homePageMenstruationEnd == 0){
                    hasEnd = true;
                    position = i;
                    break;
                }
            }
            if(hasEnd){
                DayUnitDSInput[] dayUnitDSInput = new DayUnitDSInput[2];
                dayUnitDSInput[0] = new DayUnitDSInput();
                dayUnitDSInput[0].date = recordDateSeconds +  12 * 3600;
                dayUnitDSInput[0].menstruationRecord = 255;
                dayUnitDSInput[1] = new DayUnitDSInput();
                dayUnitDSInput[1].date = dayUnitDSOutputList.get(position).date;
                dayUnitDSInput[1].menstruationRecord = 254;
                return dayUnitDSInput;
            }else {
                DayUnitDSInput[] dayUnitDSInput = new DayUnitDSInput[1];
                dayUnitDSInput[0] = new DayUnitDSInput();
                dayUnitDSInput[0].date = recordDateSeconds +  12 * 3600;
                dayUnitDSInput[0].menstruationRecord = 254;
                return dayUnitDSInput;
            }
        }else{
            DayUnitDSInput[] dayUnitDSInput = new DayUnitDSInput[2];
            dayUnitDSInput[1] = new DayUnitDSInput();
            dayUnitDSInput[1].date = recordDateSeconds +  12 * 3600;
            dayUnitDSInput[1].menstruationRecord = 254;
            long startTime = recordDateSeconds - (15 + App.memory_preference_mensesLen) * 24 * 3600;
            long endTime = recordDateSeconds;
            List<DayUnitDSOutput> dayUnitDSOutputList = dbManager.getALDayUnitDSOutputList(App.userName, startTime, endTime);
            for(int i = dayUnitDSOutputList.size() - 1; i > 0; i--){
                if(dayUnitDSOutputList.get(i -1).homePageNextMenstruation == 1 && dayUnitDSOutputList.get(i).periodAchieveConfirm > 0){
                    dayUnitDSInput[0] = new DayUnitDSInput();
                    dayUnitDSInput[0].date = dayUnitDSOutputList.get(i).date;
                    dayUnitDSInput[0].menstruationRecord = 255;
                    break;
                }
            }

            return dayUnitDSInput;
        }
    }

    private void deleteInputMensesDayNoValidRecordDatas(long recordDateSeconds, int type) {
        long startTime = getInputMensesStartTime(recordDateSeconds);
        AppLog.i("startTime:" + startTime);
        long endTime = DateUtil.getForthOrBackDateZeroTime(startTime, 15);
        AppLog.i("endTime:" + endTime);
        List<UserRecordData> userRecordDataList = dbManager.getRecordDataList(App.userName, startTime, endTime);
        //int bloodRecordNum = getBloodRecordNum(userRecordDataList);
        //AppLog.i("bloodRecordNum size:" + bloodRecordNum);

        for (int i = userRecordDataList.size() - 1; i >= 0; i--) {
            if (!UserRecordData.isMensesBlood(userRecordDataList.get(i).getMensesInfo())) {
                userRecordDataList.remove(i);
            }
        }
        if(userRecordDataList.size() != 0){
            if(type == AL_TYPE_INPUT_MENSES_START){
                for (int i = 0; i < userRecordDataList.size(); i++) {
                    if (userRecordDataList.get(i).getRecordDate() < recordDateSeconds) {
                        userRecordDataList.get(i).setMensesInfo(0);
                        userRecordDataList.get(i).setIsSynced(0);
                        dbManager.saveRecordData(userRecordDataList.get(i));
                    }
                }
            }
            if(type == AL_TYPE_INPUT_MENSES_END){
                for (int i = 0; i < userRecordDataList.size(); i++) {
                    if (userRecordDataList.get(i).getRecordDate() >= recordDateSeconds + 24*3600) {
                        userRecordDataList.get(i).setMensesInfo(0);
                        userRecordDataList.get(i).setIsSynced(0);
                        dbManager.saveRecordData(userRecordDataList.get(i));
                    }
                }
            }

            if(type == AL_TYPE_DELETE_MENSES_START){
                for (int i = 0; i < userRecordDataList.size(); i++) {
                    userRecordDataList.get(i).setMensesInfo(0);
                    userRecordDataList.get(i).setIsSynced(0);
                    dbManager.saveRecordData(userRecordDataList.get(i));
                }
            }

            if(type == AL_TYPE_DELETE_MENSES_END){
                for (int i = 0; i < userRecordDataList.size(); i++) {
                    if (userRecordDataList.get(i).getRecordDate() == recordDateSeconds + 12 * 3600) {
                        userRecordDataList.get(i).setMensesInfo(0);
                        userRecordDataList.get(i).setIsSynced(0);
                        dbManager.saveRecordData(userRecordDataList.get(i));
                    }
                }
            }
        }
    }

    public DayUnitDSInput[] getCurrentCycleInputMensesDayInput(int mensesLen){
        int validCount = dbManager.getALUserData(App.userName).validCycleCount + 1;
        long currentCycleUnitDSMensesStartConfirm = dbManager.getCurrentCycleUnitDSMensesStartConfirm(App.userName, validCount);
        long currentCycleUnitDSMensesEnd = currentCycleUnitDSMensesStartConfirm + (mensesLen - 1) * 24 * 3600;

        DayUnitDSInput[] dayUnitDSInput = new DayUnitDSInput[2];
        dayUnitDSInput[0] = new DayUnitDSInput();
        dayUnitDSInput[0].date = currentCycleUnitDSMensesStartConfirm;
        dayUnitDSInput[0].menstruationRecord = 1;
        dayUnitDSInput[1] = new DayUnitDSInput();
        dayUnitDSInput[1].date = currentCycleUnitDSMensesEnd;
        dayUnitDSInput[1].menstruationRecord = 2;

        return dayUnitDSInput;
    }

    private long getInputMensesStartTime(long recordDateSeconds) {
        long returnTime = recordDateSeconds;
        long startTime = recordDateSeconds - 14 * 24 * 3600;
        long endTime = recordDateSeconds;
        List<UserRecordData> userRecordDataList = dbManager.getRecordDataList(App.userName, startTime, endTime);
        if (userRecordDataList.size() != 0) {
            for (int i = 0; i < userRecordDataList.size(); i++) {
                if (UserRecordData.divideBytes(userRecordDataList.get(i).getMensesInfo(), 2, 0) > 0) {
                    if (userRecordDataList.get(i).getRecordDate() < returnTime)
                        returnTime = userRecordDataList.get(i).getRecordDate();
                }
            }
        }
        return  returnTime;
    }

    private int getBloodRecordNum(List<UserRecordData> userRecordDataList){
        int bloodRecordNum = 0;

        for(UserRecordData userRecordData : userRecordDataList){
            if(UserRecordData.isMensesBlood(userRecordData.getMensesInfo()))
                bloodRecordNum ++;
        }

        return bloodRecordNum;
    }

    public JSONArray getDayOutputJson(){
        JSONArray jsonArrayUserDatas = new JSONArray();
        JSONObject jsonObject;
        for(int i = 0; i < alDayOutputList.size(); i++) {

            if(!DateUtil.isValidDate(alDayOutputList.get(i).date))
                continue;

            jsonObject = new JSONObject();
            try {
                String str = DateUtil.getDateTimeStr2bit(alDayOutputList.get(i).date);
                jsonObject.put("infoDate", str);
                jsonObject.put("periodAchieveForecast", String.valueOf(alDayOutputList.get(i).periodAchieveForecast));
                jsonObject.put("periodAchieveConfirm", String.valueOf(alDayOutputList.get(i).periodAchieveConfirm));
                jsonObject.put("periodAvoidForecast", String.valueOf(alDayOutputList.get(i).periodAvoidForecast));
                jsonObject.put("periodAvoidConfirm", String.valueOf(alDayOutputList.get(i).periodAvoidConfirm));
                jsonObject.put("homePageMenstruationEnd", String.valueOf(alDayOutputList.get(i).homePageMenstruationEnd));
                jsonObject.put("homePageOvulation", String.valueOf(alDayOutputList.get(i).homePageOvulation));
                jsonObject.put("homePageConceptionChance", String.valueOf(alDayOutputList.get(i).homePageConceptionChance));
                jsonObject.put("homePageNextMenstruation", String.valueOf(alDayOutputList.get(i).homePageNextMenstruation));
                jsonObject.put("dayOfCycle", String.valueOf(alDayOutputList.get(i).dayOfCycle));

            } catch (JSONException e) {
                e.printStackTrace();
            }
            jsonArrayUserDatas.put(jsonObject);
        }
        return jsonArrayUserDatas;
    }

    public JSONObject getUserInfoJson(){

        JSONObject jsonObject = new JSONObject();
        try {
            jsonObject.put("validCycleCount", mUserData.validCycleCount);
            jsonObject.put("averageMenstruationLength",  String.valueOf(mUserData.averageMenstruationLength));
            jsonObject.put("menstruationErrorLength", String.valueOf(mUserData.menstruationLengthError));
            jsonObject.put("averageCycleLength", String.valueOf(mUserData.averageCycleLength));
            jsonObject.put("cycleErrorLength", String.valueOf(mUserData.cycleLengthError));
            jsonObject.put("averageLuteumPhaseLength", String.valueOf(mUserData.averageLuteumPhaseLength));
            jsonObject.put("abnormalCaseAlert", mUserData.abnormalCaseAlert);

        } catch (JSONException e) {
            e.printStackTrace();
        }

         return jsonObject;
    }

    public JSONArray getCycleOutputJson(){
        JSONArray jsonArrayCycleDatas = new JSONArray();
        JSONObject jsonObject;
        for(int i = 0; i < cycleOutput.length; i++) {
            if(cycleOutput[i].cycleNumber == -10){
                AppLog.i("cycleOutput[i].cycleNumber is -10, continue!");
                continue;
            }

            jsonObject = new JSONObject();
            try {
                jsonObject.put("cycleNumber",String.valueOf(cycleOutput[i].cycleNumber));
                jsonObject.put("menstruationStartForecast",String.valueOf(cycleOutput[i].menstruationStartForecast));
                jsonObject.put("menstruationEndForecast",String.valueOf(cycleOutput[i].menstruationEndForecast));
                jsonObject.put("menstruationStartConfirm",String.valueOf(cycleOutput[i].menstruationStartConfirm));
                jsonObject.put("menstruationEndConfirm",String.valueOf(cycleOutput[i].menstruationEndConfirm));
                jsonObject.put("bBTRiseDay",String.valueOf(cycleOutput[i].BBTRiseDay));
                jsonObject.put("peakDay",String.valueOf(cycleOutput[i].peakDay));
                jsonObject.put("ovulationDayForecast",String.valueOf(cycleOutput[i].ovulationDayForecast));
                jsonObject.put("ovulationDayConfirm",String.valueOf(cycleOutput[i].ovulationDayConfirm));
                jsonObject.put("ovulationDayUserRecord",String.valueOf(cycleOutput[i].ovulationDayUserRecord));
                jsonObject.put("ovulationDayUserRecordBasis",String.valueOf(cycleOutput[i].ovulationDayUserRecordBasis));
                jsonObject.put("ovulationDayBBTRiseDay",String.valueOf(cycleOutput[i].ovulationDayBBTRise));
                jsonObject.put("ovulationDayNextMenstruation",String.valueOf(cycleOutput[i].ovulationDayNextMenstruation));
                jsonObject.put("fertileStartForecast",String.valueOf(cycleOutput[i].fertileWindowStartForecast));
                jsonObject.put("fertileEndForecast",String.valueOf(cycleOutput[i].fertileWindowEndForecast));
                jsonObject.put("fertileStartConfirm",String.valueOf(cycleOutput[i].fertileWindowStartConfirm));
                jsonObject.put("fertileEndConfirm",String.valueOf(cycleOutput[i].fertileWindowEndConfirm));
                jsonObject.put("dangerStartForecast",String.valueOf(cycleOutput[i].dangerWindowStartForecast));
                jsonObject.put("dangerEndForecast",String.valueOf(cycleOutput[i].dangerWindowEndForecast));
                jsonObject.put("dangerStartConfirm",String.valueOf(cycleOutput[i].dangerWindowStartConfirm));
                jsonObject.put("dangerEndConfirm",String.valueOf(cycleOutput[i].dangerWindowEndConfirm));
                jsonObject.put("nextMenstruationStartForecast",String.valueOf(cycleOutput[i].nextMenstruationStartForecast));
                jsonObject.put("nextMenstruationEndForecast",String.valueOf(cycleOutput[i].nextMenstruationEndForecast));
                jsonObject.put("nextOvulateForecast",String.valueOf(cycleOutput[i].nextOvulationDayForecast));
                jsonObject.put("nextFertileStartForecast",String.valueOf(cycleOutput[i].nextFertileWindowStartForecast));
                jsonObject.put("nextFertileEndForecast",String.valueOf(cycleOutput[i].nextFertileWindowEndForecast));
                jsonObject.put("nextDangerStartForecast",String.valueOf(cycleOutput[i].nextDangerWindowStartForecast));
                jsonObject.put("nextDangerEndForecast",String.valueOf(cycleOutput[i].nextDangerWindowEndForecast));

            } catch (JSONException e) {
                e.printStackTrace();
            }
            jsonArrayCycleDatas.put(jsonObject);
        }
        return jsonArrayCycleDatas;
    }

    private void firstInitALInOutputSpace(){
        for(int x = 0; x < DAY_INPUT_LEN; x++){
            dayInput[x] = new DayUnitDSInput();
            dayInput[x].setData(x);
        }

        for(int x = 0; x < CYCLE_INPUT_LEN; x++){
            cycleInput[x] = new CycleUnitDS();
            cycleInput[x].setData(x);
        }

        for(int x = 0; x < CYCLE_OUT_LEN; x++){
            cycleOutput[x]= new CycleUnitDS();
            cycleOutput[x].setData(-10);
        }
    }

    private void initALOutputSpace(){
        for(int x = 0; x < CYCLE_OUT_LEN; x++){
            cycleOutput[x]= new CycleUnitDS();
            cycleOutput[x].setData(-10);
        }
    }

    private boolean isALTypeValid(int alType){
        return (alType >= 1 && alType <= 24);
    }

    public void saveALData2Sqlite(int isSynced){
        saveALData2Sqlite(mUserData, alDayOutputList, cycleOutput, isSynced);
    }

    private void saveALData2Sqlite(UserUnitDS userData, List<DayUnitDSOutput> alDayOutputList, CycleUnitDS[] cycleOutput, int isSynced){
        dbManager.getSQLiteDatabase().beginTransaction();
        saveALUserData2Sqlite(userData, isSynced);
        saveALDayOutput2Sqlite(alDayOutputList, isSynced);
        saveALCycleOutput2Sqlite(cycleOutput, isSynced);

        dbManager.getSQLiteDatabase().setTransactionSuccessful();
        dbManager.getSQLiteDatabase().endTransaction();
    }

    public void saveALUserData2Sqlite(UserUnitDS userData, int isSynced){
        dbManager.saveALUserData(userData, isSynced);
    }

    public void saveALDayOutput2Sqlite(List<DayUnitDSOutput> alDayOutputList, int isSynced){
        dbManager.saveALDayOutput(alDayOutputList, isSynced);
    }

    public void saveALCycleOutput2Sqlite(CycleUnitDS[] cycleOutput, int isSynced){
        dbManager.saveALCycleOutput(cycleOutput, isSynced);
    }

    public UserUnitDS getALUserDataFromSqlite(String userName){
        return dbManager.getALUserData(userName);
    }

    public DayUnitDSOutput[] getALDayOutputFromSqlite(String userName){
        return dbManager.getALDayOutput(userName);
    }

    public CycleUnitDS[] getALCycleOutputFromSqlite(String userName, String cycleNum){
        return dbManager.getALCycleOutput(userName, cycleNum);
    }
}

